package com.ryenlii.datatrans.core.util;

import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
import com.ryenlii.datatrans.core.constant.SysQueryMethodEnum;
import com.ryenlii.datatrans.entity.QueryModelInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

public class QueryModeUtil {
    private static final Logger log = LoggerFactory.getLogger(QueryModeUtil.class);

    /**
     * 解析select sql生成QueryModelInfo
     *
     * @param dbTypeName mysql, oracle...
     * @param selectSql
     * @return
     */
    public static QueryModelInfo parse(String dbTypeName, String selectSql) {
        QueryModelInfo queryModelInfo = new QueryModelInfo();
        DbType dbType = DbType.valueOf(dbTypeName.toLowerCase());
        List<SQLStatement> statementList = SQLUtils.parseStatements(selectSql, dbType);
        // final String format = SQLUtils.format(selectSql, dbType, SQLUtils.DEFAULT_FORMAT_OPTION);
        // log.debug("selectSql format = "+format);
        for (SQLStatement statement : statementList) {
            if (statement instanceof SQLSelectStatement selectStatement) {
                SchemaStatVisitor visitor = new SchemaStatVisitor(dbType);
                statement.accept(visitor);

                // 解析表名
                SQLSelectQueryBlock queryBlock = selectStatement.getSelect().getFirstQueryBlock();
                SQLTableSource from = queryBlock.getFrom();
                SQLExprTableSource sqlExprTableSource = (SQLExprTableSource) from;
                String tableName = sqlExprTableSource.getTableName();
                queryModelInfo.setTableName(tableName);

                // 查询列
                Collection<TableStat.Column> columns = visitor.getColumns();
                List<String> columnList = new ArrayList<>();
                columns.stream().forEach(row -> {
                    if (row.isSelect()) {
                        // 保存select字段
                        columnList.add(row.getName());
                    }
                });
                queryModelInfo.setColumnList(columnList);

                // 查询过滤条件
                List<TableStat.Condition> conditions = visitor.getConditions();
                Map<String, SysQueryMethodEnum> whereMap = new HashMap<>();
                conditions.forEach(row -> {
                    String columnName = row.getColumn().getName();
                    String operator = row.getOperator();
                    if ("=".equalsIgnoreCase(operator)) {
                        whereMap.put(columnName, SysQueryMethodEnum.eq);
                    } else if ("LIKE".equalsIgnoreCase(operator)) {
                        whereMap.put(columnName, SysQueryMethodEnum.like);
                    } else {
                        log.warn("un support operator {}; row = {}", operator, row);
                    }
                });
                queryModelInfo.setWhereMap(whereMap);
                break;
            }
        }
        return queryModelInfo;
    }

    public static void main(String[] args) {
        String selectSql = "select * from t_user where id = 1 and name like '%a%'";
    }
}
